import type { CSSProperties } from 'react';

import ButtonIcon from '@/components/ButtonIcon';

import { ThemeContext, icons } from './themeContext';

import type { ButtonProps, TooltipProps } from 'antd';

/**
 * ThemeSchemaSwitch 组件属性
 * @typedef {Object} Props
 * @property {string} [className] - 自定义 CSS 类名
 * @property {boolean} [showTooltip=true] - 是否显示工具提示
 * @property {CSSProperties} [style] - 内联样式对象
 * @property {TooltipProps['placement']} [tooltipPlacement='bottom'] - 工具提示位置
 */
interface Props {
	className?: string;
	showTooltip?: boolean;
	style?: CSSProperties;
	tooltipPlacement?: TooltipProps['placement'];
}

/**
 * 默认动画持续时间(毫秒)
 */
const DEFAULT_ANIMATION_DURATION = 400;

/**
 * 默认动画缓动函数
 */
const DEFAULT_ANIMATION_EASING = 'ease-out';

/**
 * ThemeSchemaSwitch 组件
 * 用于切换主题模式，支持动画效果
 * @param showTooltip - 是否显示提示
 * @param tooltipPlacement - 提示位置
 * @param props - 其他属性
 */
const ThemeSchemaSwitch: FC<Props> = memo(
	({ showTooltip = true, tooltipPlacement = 'bottom', ...props }) => {
		const { darkMode, themeScheme, toggleThemeScheme } = useContext(ThemeContext);

		const tooltipContent = showTooltip ? '主题模式' : '';

		/**
		 * 切换主题模式
		 * @param event - 点击事件
		 */
		const toggleDark: ButtonProps['onClick'] = event => {
			// 判断是否支持外观过渡
			const isAppearanceTransition = !window.matchMedia('(prefers-reduced-motion: reduce)').matches;

			// 如果不支持外观过渡，直接切换主题模式
			if (!isAppearanceTransition) {
				toggleThemeScheme();
				return;
			}

			// 开始视图过渡动画
			const transition = document.startViewTransition(() => {
				toggleThemeScheme();
			});

			// 如果主题方案为系统默认，则不进行动画
			if (themeScheme === 'system') return;

			// 获取点击事件的位置
			const x = event.clientX;
			const y = event.clientY;
			// 计算动画的结束半径
			const endRadius = Math.hypot(Math.max(x, innerWidth - x), Math.max(y, innerHeight - y));

			// 准备动画效果
			transition.ready.then(() => {
				const clipPath = [
					`circle(0px at ${x}px ${y}px)`,
					`circle(${endRadius}px at ${x}px ${y}px)`
				];
				document.documentElement.animate(
					{
						clipPath: darkMode ? [...clipPath].reverse() : clipPath
					},
					{
						duration: DEFAULT_ANIMATION_DURATION,
						easing: DEFAULT_ANIMATION_EASING,
						pseudoElement: darkMode ? '::view-transition-old(root)' : '::view-transition-new(root)'
					}
				);
			});
		};

		return (
			<ButtonIcon
				icon={icons[themeScheme]}
				tooltipContent={tooltipContent}
				{...props}
				tooltipPlacement={tooltipPlacement}
				onClick={toggleDark}
			/>
		);
	}
);

export default ThemeSchemaSwitch;
